<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8" />
  <title>股票涨跌分布柱状图</title>
  <script src="https://d3js.org/d3.v7.min.js"></script>
  <style>
    body {
      font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
      background-color: #f9f9f9;
      margin: 0;
      padding: 20px;
    }

    svg {
      background-color: white;
      border-radius: 10px;
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    }

    .bar {
      transition: all 0.3s ease;
    }

    .axis-label {
      font-size: 12px;
      fill: #555;
    }

    .value-label {
      font-size: 12px;
      fill: gray;
      font-weight: bold;
      text-anchor: middle;
      dominant-baseline: middle;
      pointer-events: none;
    }

    .grid-line line {
      stroke: #ddd;
      stroke-dasharray: 4;
    }

    .tooltip {
      position: absolute;
      padding: 6px 12px;
      background: rgba(0, 0, 0, 0.7);
      color: white;
      border-radius: 4px;
      font-size: 12px;
      pointer-events: none;
      opacity: 0;
      transition: opacity 0.2s;
    }
  </style>
</head>
<body>

<svg id="chart" width="900" height="450"></svg>

<!-- Tooltip 容器 -->
<div class="tooltip" id="tooltip"></div>

<script>
  const rawData = [
    { start: -11, count: 5 },
    { start: -10, count: 36 },
    { start: -9, count: 15 },
    { start: -8, count: 45 },
    { start: -7, count: 67 },
    { start: -6, count: 146 },
    { start: -5, count: 359 },
    { start: -4, count: 744 },
    { start: -3, count: 1207 },
    { start: -2, count: 1118 },
    { start: -1, count: 606 },
    { start: 0, count: 65 },
    { start: 1, count: 321 },
    { start: 2, count: 157 },
    { start: 3, count: 102 },
    { start: 4, count: 68 },
    { start: 5, count: 31 },
    { start: 6, count: 26 },
    { start: 7, count: 15 },
    { start: 8, count: 14 },
    { start: 9, count: 5 },
    { start: 10, count: 20 },
    { start: 11, count: 57 }
  ];

  const margin = { top: 40, right: 30, bottom: 60, left: 60 },
        width = 800 - margin.left - margin.right,
        height = 350;

  const svg = d3.select("#chart")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr("transform", `translate(${margin.left}, ${margin.top})`);

  // X 轴比例尺
  const x = d3.scaleBand()
    .domain(rawData.map(d => d.start.toString()))
    .range([0, width])
    .padding(0.2);

  // Y 轴比例尺
  const y = d3.scaleLinear()
    .domain([0, d3.max(rawData, d => d.count)]).nice()
    .range([height, 0]);

  // 添加网格线
  const makeYGridlines = () => d3.axisLeft(y).ticks(5);

  svg.append("g")
    .attr("class", "grid-line")
    .call(makeYGridlines()
      .tickSize(-width)
      .tickFormat('')
    );

  // 创建柱子组
  const bars = svg.selectAll(".bar-group")
    .data(rawData)
    .enter()
    .append("g")
    .attr("class", "bar-group")
    .on("mouseover", function(event, d) {
      d3.select("#tooltip")
        .style("opacity", 1)
        .html(`涨幅: ${d.start}%<br/>数量: ${d.count}`)
        .style("left", (event.pageX + 10) + "px")
        .style("top", (event.pageY - 25) + "px");
    })
    .on("mousemove", function(event) {
      d3.select("#tooltip")
        .style("left", (event.pageX + 10) + "px")
        .style("top", (event.pageY - 25) + "px");
    })
    .on("mouseout", function() {
      d3.select("#tooltip").style("opacity", 0);
    });

  // 柱子
  bars.append("rect")
    .attr("class", "bar")
    .attr("x", d => x(d.start.toString()))
    .attr("y", d => y(d.count))
    .attr("width", x.bandwidth())
    .attr("height", d => height - y(d.count))
    .attr("fill", d => (d.start >= 0 ? "#e74c3c" : "#27ae60")) // 红绿更鲜艳
    .attr("rx", 3) // 圆角
    .attr("ry", 3);

  // 数值标签
  bars.append("text")
    .attr("class", "value-label")
    .attr("x", d => x(d.start.toString()) + x.bandwidth() / 2)
    .attr("y", d => y(d.count) - 5)
    .text(d => d.count);

  // X 轴
  svg.append("g")
    .attr("transform", `translate(0,${height})`)
    .call(d3.axisBottom(x))
    .selectAll("text")
    .attr("class", "axis-label");

  // Y 轴
  svg.append("g")
    .call(d3.axisLeft(y))
    .selectAll("text")
    .attr("class", "axis-label");

  // 标题
  svg.append("text")
    .attr("x", width / 2)
    .attr("y", -15)
    .attr("text-anchor", "middle")
    .attr("font-size", "20px")
    .attr("font-weight", "bold")
    .attr("fill", "#333")
    .text("股票涨跌幅分布柱状图");

</script>

</body>
</html>